From f9616d34b5bf4bda196ed18730832d95e04947a4 Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.me>
Date: Sun, 18 Feb 2024 06:15:59 -0800
Subject: feat(user): hololive badges

---
 src/routes/user/[user]/+page.svelte | 121 ++++++++++++++++++++++++++++--------
 1 file changed, 96 insertions(+), 25 deletions(-)

(limited to 'src/routes/user/[user]/+page.svelte')

diff --git a/src/routes/user/[user]/+page.svelte b/src/routes/user/[user]/+page.svelte
index 910a99e2..0d98c9ce 100644
--- a/src/routes/user/[user]/+page.svelte
+++ b/src/routes/user/[user]/+page.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+	import { typeSchedule, type ParseResult } from '$lib/Hololive/hololive';
 	import { user, type User } from '$lib/Data/AniList/user';
 	import HeadTitle from '$lib/Home/HeadTitle.svelte';
 	import Message from '$lib/Loading/Message.svelte';
@@ -8,15 +9,20 @@
 	import locale from '$stores/locale.js';
 	import { onMount } from 'svelte';
 	import authorisedUsers from '$lib/Data/Static/authorised.json';
-	import tooltip from '$lib/Tooltip/tooltip.js';
+	import tooltip from '$lib/Tooltip/tooltip';
 	import AnimeRateLimited from '$lib/Error/AnimeRateLimited.svelte';
 	import identity from '$stores/identity';
 	import SettingHint from '$lib/Settings/SettingHint.svelte';
+	import proxy from '$lib/Utility/proxy';
+	import { parseScheduleHtml } from '$lib/Data/hololive';
+	import type { UserPreferences } from '$lib/Database/userPreferences.js';
 
 	export let data;
 
 	let userData: User | undefined = undefined;
 	let error = false;
+	let schedule: ParseResult | undefined = undefined;
+	let preferences: UserPreferences | undefined = undefined;
 
 	$: displayBadges = (username: string, badges: number | string) =>
 		$locale({
@@ -32,6 +38,26 @@
 			.catch(() => (error = true));
 	});
 
+	onMount(async () => {
+		schedule = typeSchedule(
+			parseScheduleHtml(
+				await (
+					await fetch(proxy('https://schedule.hololive.tv'), {
+						headers: {
+							Cookie: 'timezone=Asia/Tokyo'
+						}
+					})
+				).text()
+			)
+		);
+	});
+
+	$: if (userData && userData.id === $identity.id) {
+		fetch(root(`/api/preferences?id=${userData.id}`))
+			.then((rawPreferences) => rawPreferences.json())
+			.then((JSONpreferences) => (preferences = JSONpreferences));
+	}
+
 	// 8.5827814569536423841e0
 </script>
 
@@ -117,39 +143,62 @@
 						{:catch}
 							{displayBadges(userData.name, '?')}
 						{/await}
+
+						{#if schedule && preferences && preferences.pinned_hololive_streams.length > 0}
+							<p />
+
+							<div class="hololive-badges">
+								{#each preferences.pinned_hololive_streams as stream}
+									{@const avatar = schedule.dict[stream]}
+
+									{#if avatar}
+										<a
+											href={`https://www.youtube.com/results?search_query=${encodeURIComponent(
+												stream
+											)}`}
+											target="_blank"
+										>
+											<img
+												src={avatar}
+												alt="Avatar"
+												class="user-grid-hololive-badges"
+												title={stream}
+												use:tooltip
+											/>
+										</a>
+									{/if}
+								{/each}
+							</div>
+						{/if}
 					</div>
 				</div>
 			</div>
 		{/if}
 	</div>
 
-	{#if userData && userData.id === $identity.id}
-		{#await fetch(root(`/api/preferences?id=${userData.id}`)) then rawPreferences}
-			{#await rawPreferences.json() then preferences}
-				<p />
-
-				<details open>
-					<summary>{$locale().user.preferences.title}</summary>
-
-					<input
-						type="checkbox"
-						on:change={() => {
-							if (userData)
-								fetch(root(`/api/preferences?id=${userData.id}&toggleHideMissingBadges`), {
-									method: 'PUT'
-								});
-						}}
-						checked={preferences.hide_missing_badges}
-					/>
-					{$locale().user.preferences.hideMissingBadges.title}
-					<SettingHint lineBreak>{$locale().user.preferences.hideMissingBadges.hint}</SettingHint>
-				</details>
-			{/await}
-		{/await}
+	{#if preferences}
+		<p />
+
+		<details open>
+			<summary>{$locale().user.preferences.title}</summary>
+
+			<input
+				type="checkbox"
+				on:change={() => {
+					if (userData)
+						fetch(root(`/api/preferences?id=${userData.id}&toggleHideMissingBadges`), {
+							method: 'PUT'
+						});
+				}}
+				checked={preferences.hide_missing_badges}
+			/>
+			{$locale().user.preferences.hideMissingBadges.title}
+			<SettingHint lineBreak>{$locale().user.preferences.hideMissingBadges.hint}</SettingHint>
+		</details>
 	{/if}
 {/if}
 
-<style>
+<style lang="scss">
 	#user-grid-content {
 		display: flex;
 		flex-wrap: wrap;
@@ -185,4 +234,26 @@
 		visibility: hidden;
 		height: 4.5em;
 	}
+
+	.user-grid-hololive-badges {
+		$transition: transform 0.3s ease;
+		$size: 2em;
+
+		border-radius: 8px;
+		width: $size;
+		height: $size;
+		object-fit: cover;
+		transition: $transition;
+
+		&:hover {
+			z-index: 2;
+			transition: $transition;
+			transform: scale(1.1);
+		}
+	}
+
+	.hololive-badges {
+		display: flex;
+		gap: 0.75em;
+	}
 </style>
-- 
cgit v1.2.3

